/**
 * 初始化 图表
 * @param diagram
 */
function initDiagram(diagram, canEdit){
    canEdit = canEdit==undefined?false:canEdit;
    var $ = go.GraphObject.make;  // for conciseness in defining templates

    //开始 节点模板
    diagram.nodeTemplateMap.add("Start",
        $(go.Node, "Table", nodeStyle(),
            $(go.Panel, "Auto",
                $(go.Shape, "Circle",
                    { minSize: new go.Size(20, 20), fill: "lightgreen", strokeWidth: 0 }),
                $(go.TextBlock, "Start", {font: "bold 11pt Helvetica, Arial, sans-serif", stroke: "#3f3838"},
                    new go.Binding("text"))
            )
        ));

    //结束 节点模板
    diagram.nodeTemplateMap.add("End",
        $(go.Node, "Table", nodeStyle(),
            $(go.Panel, "Auto",
                $(go.Shape, "Circle",
                    { minSize: new go.Size(20, 20), fill: "#d13900", strokeWidth: 0 }),
                $(go.TextBlock, "End", {font: "bold 11pt Helvetica, Arial, sans-serif", stroke: "#3f3838"},
                    new go.Binding("text"))
            )
        ));

    /**
     * 默认 节点模板
     * @param text、color、tip、size
     * @size格式 "100 30"
     */
    diagram.nodeTemplate =
        $(go.Node, "Auto",
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            new go.Binding("desiredSize", "size", go.Size.parse),
            // define the node's outer shape, which will surround the TextBlock
            $(go.Shape, "RoundedRectangle",
                {
                    parameter1: 20,  // the corner has a large radius
                    fill: $(go.Brush, "Linear", { 0: "rgb(244, 244, 244)", 1: "rgb(216, 214, 214)" }), //背景色
                    stroke: "#ddd", //边框
                    portId: "",  // this Shape is the Node's port, not the whole Node
                    fromLinkable: true, fromLinkableSelfNode: true, fromLinkableDuplicates: true,
                    toLinkable: true, toLinkableSelfNode: true, toLinkableDuplicates: true,
                    cursor: "pointer"
                }, new go.Binding("fill", "color")), //背景色
            $(go.TextBlock,
                {
                    font: "bold 11pt helvetica, bold arial, sans-serif",
                    margin: 5,
                    editable: canEdit  // 节点是否可编辑
                }, new go.Binding("text").makeTwoWay()),

            { // https://gojs.net/beta/samples/kittenMonitor.html
                toolTip:
                    $("ToolTip",
                        $(go.Panel, "Vertical",
//                                              $(go.Picture, new go.Binding("source", "src", function(s) { return "images/" + s + ".png"; })),
                            $(go.TextBlock, { margin: 5 },  new go.Binding("text", "tip"))))
            }
        );


    /**
     * 链接 模板
     * @param lineColor
     */
    diagram.linkTemplate =
        $(go.Link,  // the whole link panel
            {        //弯曲=Bezier、直线=JumpGap、JumpOver
                curve: go.Link.Bezier, adjusting: go.Link.Stretch,
                reshapable: true, relinkableFrom: true, relinkableTo: true,
                toShortLength: 8,
            }, //
            new go.Binding("points").makeTwoWay(),
            new go.Binding("curviness"), //弯曲

            $(go.Shape,  // the link shape  虚线,strokeDashArray: [5, 5]
                { strokeWidth: 2, stroke: "#969191"}, new go.Binding("stroke", "lineColor")),
            $(go.Shape,  // the arrowhead
                {toArrow: "standard" , fill: "#969191", stroke: "lineColor"}, new go.Binding("fill", "lineColor") ),
            $(go.Panel, "Auto",
                $(go.Shape,  // the label background, which becomes transparent around the edges
                    {
                        fill: $(go.Brush, "Radial",
                            { 0: "rgb(240, 240, 240)", 0.3: "rgb(240, 240, 240)", 1: "rgba(240, 240, 240, 0)" }),
                        stroke: null
                    }), // 备注面板颜色 , new go.Binding("fill", "color")  // stroke=边框
                $(go.TextBlock, "transition",  // the label text
                    {
                        textAlign: "center",
                        font: "9pt helvetica, arial, sans-serif",
                        margin: 4,
                        editable: canEdit  // 线 备注是否可修改
                    },
                    // editing the text automatically updates the model data
                    new go.Binding("text").makeTwoWay())
            )
        );


    // 选中 效果
    //diagram.nodeTemplate.selectionAdornmentTemplate =
    //    $(go.Adornment, "Spot",
    //        $(go.Panel, "Auto",
    //            $(go.Shape, { stroke: "#f00", strokeWidth: 2, fill: "transparent" }),
    //            $(go.Placeholder)  // a Placeholder sizes itself to the selected Node
    //        )
    //    ); // end Adornment

    // 监听是否有修改
    //diagram.addDiagramListener("Modified", function(e) {
    //    var button = document.getElementById("SaveButton");
    //    if (button) button.disabled = !diagram.isModified;
    //    var idx = document.title.indexOf("*");
    //    if (diagram.isModified) {
    //        if (idx < 0) document.title += "*";
    //    } else {
    //        if (idx >= 0) document.title = document.title.substr(0, idx);
    //    }
    //});

}


function nodeStyle() {
    return [
        // The Node.location comes from the "loc" property of the node data,
        // converted by the Point.parse static method.
        // If the Node.location is changed, it updates the "loc" property of the node data,
        // converting back using the Point.stringify static method.
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        {
            // the Node.location is at the center of each node
            locationSpot: go.Spot.Center
        }
    ];
}

// Some links need a custom to or from spot
function spotConverter(dir) {
    if (dir === "left") return go.Spot.LeftSide;
    if (dir === "right") return go.Spot.RightSide;
    if (dir === "top") return go.Spot.TopSide;
    if (dir === "bottom") return go.Spot.BottomSide;
    if (dir === "rightsingle") return go.Spot.Right;
}
